// ArchiveOpenCallback.h

#ifndef __ARCHIVE_OPEN_CALLBACK_H
#define __ARCHIVE_OPEN_CALLBACK_H

#include <atlbase.h>

#include "Common/FileSystem/FileFind.h"

#ifndef _NO_CRYPTO
#include "Common/COM/IPassword.h"
#endif
#include "Common/Archive/IArchive.h"

#ifdef _NO_CRYPTO

//this def was removing cryptography from interfaces
#define INTERFACE_IOpenCallbackUI_Crypto(x)

#endif

  

//AM: There was no GUID increased 0 -> 2
//GUID from IFileExtractCallback.h
MIDL_INTERFACE("23170F69-40C1-278A-0000-000120070000")
IOpenCallbackUI : public IUnknown
{
  
	//INTERFACE IOpenCallbackUI
	STDMETHOD(Open_CheckBreak)() PURE;
	STDMETHOD(Open_SetTotal)(const UINT64 *files, const UINT64 *bytes) PURE;
	STDMETHOD(Open_SetCompleted)(const UINT64 *files, const UINT64 *bytes) PURE;
  
	//INTERFACE IOpenCallbackUI_Crypto
	STDMETHOD(Open_CryptoGetTextPassword)(BSTR *password) PURE;
	STDMETHOD(Open_GetPasswordIfAny)(CString &password) PURE;
	virtual bool Open_WasPasswordAsked() PURE;
	virtual void Open_ClearPasswordWasAskedFlag() PURE;
};

namespace Common
{
namespace Archive
{

//Used only in OpenArchive	
class ATL_NO_VTABLE COpenCallbackImp:
	public CComObjectRootEx<CComSingleThreadModel>,
  public IArchiveOpenCallback,
  public IArchiveOpenVolumeCallback,
  #ifndef _NO_CRYPTO
  public ICryptoGetTextPassword,
  #endif
  public IArchiveOpenSetSubArchiveName
{
public:

	BEGIN_COM_MAP(COpenCallbackImp)
		COM_INTERFACE_ENTRY(IArchiveOpenCallback)
		COM_INTERFACE_ENTRY(IArchiveOpenVolumeCallback)
#ifndef _NO_CRYPTO
		COM_INTERFACE_ENTRY(ICryptoGetTextPassword)
#endif
		COM_INTERFACE_ENTRY(IArchiveOpenSetSubArchiveName)
	END_COM_MAP()



	DECLARE_PROTECT_FINAL_CONSTRUCT()

	HRESULT FinalConstruct()
	{
		return S_OK;
	}

	void FinalRelease()
	{
	}

 /* #ifndef _NO_CRYPTO
  MY_UNKNOWN_IMP3(
      IArchiveOpenVolumeCallback,
      ICryptoGetTextPassword,
      IArchiveOpenSetSubArchiveName
      )
  #else
  MY_UNKNOWN_IMP2(
      IArchiveOpenVolumeCallback,
      IArchiveOpenSetSubArchiveName
      )
  #endif */

  //INTERFACE IArchiveOpenCallback
  STDMETHOD(SetTotal)(const UINT64 *files, const UINT64 *bytes); 
  STDMETHOD(SetCompleted)(const UINT64 *files, const UINT64 *bytes);
  
  //INTERFACE IArchiveOpenVolumeCallback
  STDMETHOD(GetProperty)(PROPID propID, PROPVARIANT *value) ; 
  STDMETHOD(GetStream)(const wchar_t *name, IInStream **inStream) ;

  #ifndef _NO_CRYPTO
  STDMETHOD(CryptoGetTextPassword)(BSTR *password);
  #endif

  STDMETHOD(SetSubArchiveName(const wchar_t *name))
  {
    _subArchiveMode = true;
    _subArchiveName = name;
    TotalSize = 0;
    return  S_OK;
  }

private:
  CString _folderPrefix;
  Common::FileSystem::File::CFileInfo _fileInfo;
  bool _subArchiveMode;
  CString _subArchiveName;
public:
  CStringVector FileNames;
  IOpenCallbackUI *Callback;
  CComPtr<IArchiveOpenCallback> ReOpenCallback;
  UINT64 TotalSize;

  COpenCallbackImp(): Callback(NULL) {}
  void Init(const CString &folderPrefix, const CString &fileName)
  {
    _folderPrefix = folderPrefix;
    if (!_fileInfo.Find(_folderPrefix + fileName))
      throw 1;
    FileNames.clear();
    _subArchiveMode = false;
    TotalSize = 0;
  }
  int FindName(const CString &name);
};

}
}

#endif
